var EXPORTED_SYMBOLS = ["MLDonkeyProtocol"];

Components.utils.import("resource://mldonkeyff/MLDonkeyUtils.js");
Components.utils.import("resource://mldonkeyff/MLDonkeyProtocolTypes.js");
Components.utils.import("resource://mldonkeyff/MLDonkeyConstants.js");

Components.utils.import("resource://commons/HashMap.js");

function MLDonkeyProtocol(_mldonkeyClient) {
	//
	var mldonkeyClient = _mldonkeyClient;
	var mldonkeyData = mldonkeyClient.getMLDonkeyData();

	// Setting protocol version
	mldonkeyData.protocolData.client = MLDonkeyProtocol.PROTOCOL_VERSION;

	/*
	 * Methods
     * 
     * Send methods don't need to write message length and opcode. Those are
     * automatically added on send cache on exit from the send method.
     */
	this.protocolSEND_COREPROTOCOL = function() {
		mldonkeyClient.writeInt32(mldonkeyData.protocolData.client);
	};
	
	this.protocolSEND_CONNECT_MORE = function() {
		// Nothing to send
	};
	
	this.protocolSEND_CLEAN_OLD = function() {
		// Nothing to send
	};
	
	this.protocolSEND_KILL_CORE = function() {
		// Nothing to send
	};
	
	this.protocolSEND_EXTEND_SEARCH = function() {
		// Nothing to send
	};
	
	this.protocolSEND_DLLINK = function() {
		throw "TODO";
	};
	
	this.protocolSEND_REMOVE_SERVER = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SAVE_OPTION = function() {
		throw "TODO";
	};
	
	this.protocolSEND_REMOVE_DOWNLOAD = function() {
		throw "TODO";
	};
	
	this.protocolSEND_GET_SERVER_USERS = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SAVE_FILE_AS = function() {
		throw "TODO";
	};
	
	this.protocolSEND_ADD_CLIENT_FRIEND = function() {
		throw "TODO";
	};
	
	this.protocolSEND_ADD_USER_FRIEND = function() {
		throw "TODO";
	};
	
	this.protocolSEND_REMOVE_FRIEND = function() {
		throw "TODO";
	};
	
	this.protocolSEND_REMOVE_ALL_FRIENDS = function() {
		// Nothing to send
	};
	
	this.protocolSEND_CONNECT_SERVER = function() {
		throw "TODO";
	};
	
	this.protocolSEND_DISCONNECT_SERVER = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SWITCH_DOWNLOAD = function() {
		throw "TODO";
	};
	
	this.protocolSEND_VERIFY_ALL_CHUNKS = function() {
		throw "TODO";
	};
	
	this.protocolSEND_OLD_CLOSE_SEARCH = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SET_OPTION = function() {
		throw "TODO";
	};
	
	this.protocolSEND_CONSOLEMSG = function() {
		throw "TODO";
	};
	
	this.protocolSEND_PREVIEW = function() {
		throw "TODO";
	};
	
	this.protocolSEND_CONNECT_FRIEND = function() {
		throw "TODO";
	};
	
	this.protocolSEND_GET_CLIENT_INFO = function() {
		throw "TODO";
	};
	
	this.protocolSEND_GET_FILE_INFO = function() {
		throw "TODO";
	};
	
	this.protocolSEND_ENABLE_NETWORK = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SEARCH_QUERY = function() {
		throw "TODO";
	};
	
	this.protocolSEND_MESSAGE_TO_CLIENT = function() {
		throw "TODO";
	};
	
	this.protocolSEND_GET_CONNECTED_SERVERS = function() {
		// Nothing to send but... something to reset??? -> mldonkeyData.serversInfo.clear();
	};
	
	this.protocolSEND_GET_DOWNLOADING_FILES = function() {
		// Nothing to send
	};
	
	this.protocolSEND_GET_DOWNLOADED_FILES = function() {
		// Nothing to send
	};
	
	this.protocolSEND_GUIEXTENSION = function() {
		mldonkeyClient.writeInt16(1);
		mldonkeyClient.writeInt32(1);
		mldonkeyClient.writeInt8(1);
	};
	
	this.protocolSEND_REFRESH_UPLOAD_STATS = function() {
		// Nothing to send
	};
	
	this.protocolSEND_DOWNLOAD = function() {
		throw "TODO";
	};
	
	this.protocolSEND_SET_FILE_PRIO = function() {
		throw "TODO";
	};
	
	this.protocolSEND_PASSWORD = function() {
		mldonkeyClient.writeString(mldonkeyClient.getPassword());
		mldonkeyClient.writeString(mldonkeyClient.getUsername());
	};
	
	this.protocolSEND_CLOSE_SEARCH = function() {
		throw "TODO";
	};
	
	this.protocolSEND_ADD_SERVER = function() {
		throw "TODO";
	};
	
	this.protocolSEND_MESSAGE_VERSION = function() {
		throw "TODO";
	};

	/*
	 * Receive methods don't need to read message length and opcode. Those are
	 * automatically readed before the call of the receive method.
	 */

	this.protocolRECEIVE_COREPROTOCOL = function() {
		mldonkeyClient.setConnected(true);
		//
		mldonkeyData.protocolData.server = mldonkeyClient.readInt32();
		//
		if ((mldonkeyData.protocolData.server - mldonkeyData.protocolData.client) <= 0) {
			mldonkeyData.protocolData.used = mldonkeyData.protocolData.server;
		} else {
			mldonkeyData.protocolData.used = mldonkeyData.protocolData.client;
		}
		var trailData1 = /* ; */mldonkeyClient.readInt32();
		var trailData2 = /* D */mldonkeyClient.readInt32();
		dump("Core protocol:\r\n\tServer: " + mldonkeyData.protocolData.server + "\r\n\t;: " + String.fromCharCode(trailData1) + "\r\n\tD: " + String.fromCharCode(trailData2) + "\r\n\tIs connected: " + mldonkeyClient.isConnected() + "\r\n");
		//
		mldonkeyClient.sendMessage(MLDonkeyProtocol.SEND_GUIEXTENSION);
		mldonkeyClient.sendMessage(MLDonkeyProtocol.SEND_PASSWORD);
	};
	
	this.protocolRECEIVE_OPTIONS_INFO = function() {
		var listLen = mldonkeyClient.readInt16();
		for(var i=0; i<listLen; i++) {
			var key = mldonkeyClient.readString();
			var value = mldonkeyClient.readString();
			//
			mldonkeyData.options[key] = value;
			// dump("protocolRECEIVE_OPTIONS_INFO-> key: " + key + " value: " + value + "\r\n");
		}
	};
	
	this.protocolRECEIVE_DEFINE_SEARCH = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_RESULT_INFO = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_SEARCH_RESULT = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_FILE_UPDATE_AVAILABILITY = function() {
		// TODO : questa struttura dev'essere condivisa con i file in download
		mldonkeyData.fileUpdateAvailability.fileNumber = mldonkeyClient.readInt32();
		mldonkeyData.fileUpdateAvailability.clientNumber = mldonkeyClient.readInt32();
		mldonkeyData.fileUpdateAvailability.availability = mldonkeyClient.readString();
		// dump(mldonkeyData.fileUpdateAvailability);
	};
	
	this.protocolRECEIVE_FILE_ADD_SOURCE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_SERVER_STATE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_CLIENT_INFO = function() {
		throw "TODO";
		// TODO : Problema con la lettura del tipo di client		
		var clientInfo = new MLDonkeyClientInfo();
		//
		clientInfo.identifier = mldonkeyClient.readInt32();
		clientInfo.networkIdentifier = mldonkeyClient.readInt32();
		clientInfo.kind.readKind(mldonkeyClient);
		clientInfo.connectionState.readConnectionState(mldonkeyClient);
		//
		clientInfo.type = mldonkeyClient.readInt8();
		// List of tag
		var listLen = mldonkeyClient.readInt16();
		for(var i=0; i<listLen; i++) {
			var tag = new MLDonkeyTag();
			tag.readTag(mldonkeyClient);
			clientInfo.metadata[i] = tag;
		}
		clientInfo.name = mldonkeyClient.readString();
		clientInfo.rating = mldonkeyClient.readInt32();
		clientInfo.software = mldonkeyClient.readString();
		clientInfo.downloaded = mldonkeyClient.readInt64();
		clientInfo.uploaded = mldonkeyClient.readInt64();
		clientInfo.uploadFileName = mldonkeyClient.readString();
		clientInfo.connectTime = mldonkeyClient.readInt32();
		clientInfo.emuleMod = mldonkeyClient.readString();
		clientInfo.release = mldonkeyClient.readString();
		clientInfo.suiVerified = mldonkeyClient.readInt8();
		// dump(clientInfo);
		//
		mldonkeyData.clientsInfo[clientInfo.identifier] = clientInfo;
	};
	
	this.protocolRECEIVE_CLIENT_STATE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_CONSOLE = function() {
		// TODO : Per ora posso ignorarla
		var consoleLine = mldonkeyClient.readString();
	};
	
	this.protocolRECEIVE_NETWORK_INFO = function() {
		var identifier = mldonkeyClient.readInt32();
		var name = mldonkeyClient.readString();
		var enabled = mldonkeyClient.readBoolean();
		var configFile = mldonkeyClient.readString();
		var bytesUploaded = mldonkeyClient.readInt64();
		var bytesDownloaded = mldonkeyClient.readInt64();
		var connectedServers = mldonkeyClient.readInt32();
		var flags = mldonkeyClient.readList(MLDonkeyConstants.INT16_TYPE);
		//
		var networkInfo = new MLDonkeyNetworkInfo(identifier, name, enabled, configFile, bytesUploaded, bytesDownloaded, connectedServers, flags);
		// dump(networkInfo);
		//
		mldonkeyData.networksInfo[networkInfo.getIdentifier()] = networkInfo;
	};
	
	this.protocolRECEIVE_USER_INFO = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_SERVER_INFO = function() {
		var serverInfo = new MLDonkeyServerInfo();
		//
		serverInfo.identifier = mldonkeyClient.readInt32();
		serverInfo.networkIdentifier = mldonkeyClient.readInt32();
		serverInfo.internetAddress.readAddress(mldonkeyClient);
		serverInfo.serverPort = mldonkeyClient.readInt16();
		serverInfo.serverScore = mldonkeyClient.readInt32();
		// List of tag
		var listLen = mldonkeyClient.readInt16();
		for(var i=0; i<listLen; i++) {
			var tag = new MLDonkeyTag();
			tag.readTag(mldonkeyClient);
			serverInfo.metadata[i] = tag;
		}
		serverInfo.numberOfUsers = mldonkeyClient.readInt64();
		serverInfo.numberOfFiles = mldonkeyClient.readInt64();
		serverInfo.connectionState.readConnectionState(mldonkeyClient);
		serverInfo.serverName = mldonkeyClient.readString();
		serverInfo.serverDescription = mldonkeyClient.readString();
		serverInfo.preferred = mldonkeyClient.readInt8();
		serverInfo.serverVersion = mldonkeyClient.readString();
		serverInfo.maxUsers = mldonkeyClient.readInt64();
		serverInfo.lowIDUsers = mldonkeyClient.readInt64();
		serverInfo.softLimit = mldonkeyClient.readInt64();
		serverInfo.hardLimit = mldonkeyClient.readInt64();
		serverInfo.ping = mldonkeyClient.readInt32();
		// 
		mldonkeyData.serversInfo.put(serverInfo.identifier, serverInfo);
	};
	
	this.protocolRECEIVE_MESSAGE_FROM_CLIENT = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_CONNECTED_SERVER = function() {
		var listLen = mldonkeyClient.readInt16();
		
		dump("MLDonkeyProtocol: " + "Num of connected servers: " + listLen + "\r\n");
		
		for(var i=0; i<listLen; i++) {
			this.protocolRECEIVE_SERVER_INFO();
		}
	};
	
	this.protocolRECEIVE_ROOM_INFO = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_SHARED_FILE_UPLOAD = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_ADD_SECTION_OPTION = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_ADD_PLUGIN_OPTION = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_FILE_DOWNLOAD_UPDATE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_BAD_PASSWORD = function() {
		MLDonkeyUtils.getPromptService().alert(null, MLDonkeyUtils.getStrings().getString("badPassword"), MLDonkeyUtils.getStrings().getString("badPassword"));
	};
	
	this.protocolRECEIVE_SHARED_FILE_INFO = function() {
		throw "TODO";
		// Problemi
		var sharedFileInfo = new MLDonkeySharedFileInfo();
		//
		sharedFileInfo.identifier = mldonkeyClient.readInt32();
		sharedFileInfo.networkIdentifier = mldonkeyClient.readInt32();
		sharedFileInfo.fileName = mldonkeyClient.readString();
		sharedFileInfo.fileSize = mldonkeyClient.readInt64();
		sharedFileInfo.bytesUploaded = mldonkeyClient.readInt64();
		sharedFileInfo.numOfRequests = mldonkeyClient.readInt32();
		// dump(sharedFileInfo);
		//
		mldonkeyData.sharedFilesInfo[sharedFileInfo.identifier] = sharedFileInfo;
	};
	
	this.protocolRECEIVE_CLIENT_STATS = function() {
		mldonkeyData.clientStats.totalUploaded = mldonkeyClient.readInt64();
		mldonkeyData.clientStats.totalDownloaded = mldonkeyClient.readInt64();
		mldonkeyData.clientStats.totalShared = mldonkeyClient.readInt64();
		mldonkeyData.clientStats.numberOfSharedFiles = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.tcpUploadRate = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.tcpDownloadRate = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.udpUploadRate = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.udpDownloadRate = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.numberOfCurrentDownloads = mldonkeyClient.readInt32();
		mldonkeyData.clientStats.numberOfDownloadsFinished = mldonkeyClient.readInt32();
		// List of (Int32, Int32) - Networks identifiers, and the corresponding number of connected servers
		var listLen = mldonkeyClient.readInt16();
		for(var i=0; i < listLen; i++) {
			var networkIdentifier = mldonkeyClient.readInt32();
			var connectedServer = mldonkeyClient.readInt32();
			//
			mldonkeyData.clientStats.networkIdentifierToConnectedServersMap[networkIdentifier] = connectedServer;
		}
		// dump(mldonkeyData.clientStats);
	};
	
	this.protocolRECEIVE_FILE_REMOVE_SOURCE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_CLEAN_TABLE = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_DOWNLOAD = function() {
		
		throw "TODO";
	};
	
	this.protocolRECEIVE_DOWNLOADING_LIST = function() {
		throw "TODO";
	};
	
	this.protocolRECEIVE_DOWNLOADED_LIST = function() {
		throw "TODO";
	};

	// Create protocol functions maps
	var _protocolSendCodeToLiteralMap = new Array();
	var _protocolRecvCodeToLiteralMap = new Array();
	var _protocolLiteralToCodeMap = new Array();
	var _protocolLiteralToFunctionMap = new Array();
	//
	for (att in this) {
		if (att.substring(0, MLDonkeyProtocol._protocolPrefix.length) == MLDonkeyProtocol._protocolPrefix) {
			var protocolCode = att.substring(MLDonkeyProtocol._protocolPrefix.length, att.length);
			var evalOfProtocolCode = MLDonkeyProtocol[protocolCode];
			var fn = this[att];
			//
			if (evalOfProtocolCode == null) {
				// continue;
				throw "Unknown protocol code (Attribute: " + att + ", Protocol code: " + protocolCode + ")";
			}
			//
			if (protocolCode.substring(0, MLDonkeyProtocol._sendProtocolPrefix.length) == MLDonkeyProtocol._sendProtocolPrefix) {
				_protocolSendCodeToLiteralMap[evalOfProtocolCode] = protocolCode
				_protocolLiteralToCodeMap[protocolCode] = evalOfProtocolCode;
				_protocolLiteralToFunctionMap[protocolCode] = fn;
			} else if (protocolCode.substring(0, MLDonkeyProtocol._recvProtocolPrefix.length) == MLDonkeyProtocol._recvProtocolPrefix) {
				_protocolRecvCodeToLiteralMap[evalOfProtocolCode] = protocolCode;
				_protocolLiteralToCodeMap[protocolCode] = evalOfProtocolCode;
				_protocolLiteralToFunctionMap[protocolCode] = fn;
			} else {
				throw "Unknown protocol function (Attribute: " + att + ", Protocol code: " + protocolCode + ")";
			}
		}
	}
	
	this.getRecvProtocolFunctionFromOpCode = function(opCode) {
		var literal = _protocolRecvCodeToLiteralMap[opCode];
		//
		if (literal == null)
			throw "Unknown receive opCode (OpCode: " + opCode + ")";
		//
		return _protocolLiteralToFunctionMap[literal];
	};

	this.getRecvProtocolOpCodeToLiteral = function(opCode) {
		var literal = _protocolRecvCodeToLiteralMap[opCode];
		//
		if (literal == null)
			throw "Unknown receive opCode (OpCode: " + opCode + ")";
		//
		return literal;
	};

	this.getSendProtocolFunctionFromOpCode = function(opCode) {
		var literal = _protocolSendCodeToLiteralMap[opCode];
		//
		if (literal == null)
			throw "Unknown send opCode (OpCode: " + opCode + ")";
		//
		return _protocolLiteralToFunctionMap[literal];
	};

	this.getSendProtocolOpCodeToLiteral = function(opCode) {
		var literal = _protocolSendCodeToLiteralMap[opCode];
		//
		if (literal == null)
			throw "Unknown send opCode (OpCode: " + opCode + ")";
		//
		return literal;
	};
}

// Utility
MLDonkeyProtocol._protocolPrefix = "protocol";
MLDonkeyProtocol._sendProtocolPrefix = "SEND_";
MLDonkeyProtocol._recvProtocolPrefix = "RECEIVE_";

// Protocol Version
MLDonkeyProtocol.PROTOCOL_VERSION = 41;

// Send OpCode /////////////////////////////////////////////////////////////////////////////////////////////////////
MLDonkeyProtocol.SEND_COREPROTOCOL = 0;
MLDonkeyProtocol.SEND_CONNECT_MORE = 1;
MLDonkeyProtocol.SEND_CLEAN_OLD = 2;
MLDonkeyProtocol.SEND_KILL_CORE = 3;
MLDonkeyProtocol.SEND_EXTEND_SEARCH = 4;
MLDonkeyProtocol.SEND_DLLINK = 8;
MLDonkeyProtocol.SEND_REMOVE_SERVER = 9;
MLDonkeyProtocol.SEND_SAVE_OPTION = 10;
MLDonkeyProtocol.SEND_REMOVE_DOWNLOAD = 11;
MLDonkeyProtocol.SEND_GET_SERVER_USERS = 12;
MLDonkeyProtocol.SEND_SAVE_FILE_AS = 13;
MLDonkeyProtocol.SEND_ADD_CLIENT_FRIEND = 14;
MLDonkeyProtocol.SEND_ADD_USER_FRIEND = 15;
MLDonkeyProtocol.SEND_REMOVE_FRIEND = 16;
MLDonkeyProtocol.SEND_REMOVE_ALL_FRIENDS = 17;
MLDonkeyProtocol.SEND_CONNECT_SERVER = 21;
MLDonkeyProtocol.SEND_DISCONNECT_SERVER = 22;
MLDonkeyProtocol.SEND_SWITCH_DOWNLOAD = 23;
MLDonkeyProtocol.SEND_VERIFY_ALL_CHUNKS = 24;
MLDonkeyProtocol.SEND_OLD_CLOSE_SEARCH = 27;
MLDonkeyProtocol.SEND_SET_OPTION = 28;
MLDonkeyProtocol.SEND_CONSOLEMSG = 29;
MLDonkeyProtocol.SEND_PREVIEW = 30;
MLDonkeyProtocol.SEND_CONNECT_FRIEND = 31;
MLDonkeyProtocol.SEND_GET_CLIENT_INFO = 36;
MLDonkeyProtocol.SEND_GET_FILE_INFO = 37;
MLDonkeyProtocol.SEND_ENABLE_NETWORK = 40;
MLDonkeyProtocol.SEND_SEARCH_QUERY = 42;
MLDonkeyProtocol.SEND_MESSAGE_TO_CLIENT = 43;
MLDonkeyProtocol.SEND_GET_CONNECTED_SERVERS = 44;
MLDonkeyProtocol.SEND_GET_DOWNLOADING_FILES = 45;
MLDonkeyProtocol.SEND_GET_DOWNLOADED_FILES = 46;
MLDonkeyProtocol.SEND_GUIEXTENSION = 47;
MLDonkeyProtocol.SEND_REFRESH_UPLOAD_STATS = 49;
MLDonkeyProtocol.SEND_DOWNLOAD = 50;
MLDonkeyProtocol.SEND_SET_FILE_PRIO = 51;
MLDonkeyProtocol.SEND_PASSWORD = 52;
MLDonkeyProtocol.SEND_CLOSE_SEARCH = 53;
MLDonkeyProtocol.SEND_ADD_SERVER = 54;
MLDonkeyProtocol.SEND_MESSAGE_VERSION = 55;

// Receive OpCode //////////////////////////////////////////////////////////////////////////////////////////////////
MLDonkeyProtocol.RECEIVE_COREPROTOCOL = 0;
MLDonkeyProtocol.RECEIVE_OPTIONS_INFO = 1;
MLDonkeyProtocol.RECEIVE_DEFINE_SEARCH = 3;
MLDonkeyProtocol.RECEIVE_RESULT_INFO = 4;
MLDonkeyProtocol.RECEIVE_SEARCH_RESULT = 5;
MLDonkeyProtocol.RECEIVE_FILE_UPDATE_AVAILABILITY = 9;
MLDonkeyProtocol.RECEIVE_FILE_ADD_SOURCE = 10;
MLDonkeyProtocol.RECEIVE_SERVER_STATE = 13;
MLDonkeyProtocol.RECEIVE_CLIENT_INFO = 15;
MLDonkeyProtocol.RECEIVE_CLIENT_STATE = 16;
MLDonkeyProtocol.RECEIVE_CONSOLE = 19;
MLDonkeyProtocol.RECEIVE_NETWORK_INFO = 20;
MLDonkeyProtocol.RECEIVE_USER_INFO = 21;
MLDonkeyProtocol.RECEIVE_SERVER_INFO = 26;
MLDonkeyProtocol.RECEIVE_MESSAGE_FROM_CLIENT = 27;
MLDonkeyProtocol.RECEIVE_CONNECTED_SERVER = 28;
MLDonkeyProtocol.RECEIVE_ROOM_INFO = 31;
MLDonkeyProtocol.RECEIVE_SHARED_FILE_UPLOAD = 34;
MLDonkeyProtocol.RECEIVE_ADD_SECTION_OPTION = 36;
MLDonkeyProtocol.RECEIVE_ADD_PLUGIN_OPTION = 38;
MLDonkeyProtocol.RECEIVE_FILE_DOWNLOAD_UPDATE = 46;
MLDonkeyProtocol.RECEIVE_BAD_PASSWORD = 47;
MLDonkeyProtocol.RECEIVE_SHARED_FILE_INFO = 48;
MLDonkeyProtocol.RECEIVE_CLIENT_STATS = 49;
MLDonkeyProtocol.RECEIVE_FILE_REMOVE_SOURCE = 50;
MLDonkeyProtocol.RECEIVE_CLEAN_TABLE = 51;
MLDonkeyProtocol.RECEIVE_DOWNLOAD = 52;
MLDonkeyProtocol.RECEIVE_DOWNLOADING_LIST = 53;
MLDonkeyProtocol.RECEIVE_DOWNLOADED_LIST = 54;
